package com.rchat.pocmini.service;

import android.app.AlertDialog;
import android.app.Notification;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.Vibrator;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.telephony.PhoneStateListener;
import android.view.KeyEvent;
import android.view.WindowManager;

import com.airtalkee.sdk.AirtalkeeAccount;
import com.airtalkee.sdk.AirtalkeeSessionManager;
import com.airtalkee.sdk.OnAccountListener;
import com.airtalkee.sdk.OnMediaListener;
import com.airtalkee.sdk.OnMessageListener;
import com.airtalkee.sdk.OnMessagePttListener;
import com.airtalkee.sdk.entity.AirContact;
import com.airtalkee.sdk.entity.AirMessage;
import com.airtalkee.sdk.entity.AirSession;
import com.aso.common.sp.SPHelper;
import com.aso.common.utils.AudioUtils;
import com.aso.common.utils.ToastUtils;
import com.inuker.bluetooth.library.BluetoothClient;
import com.inuker.bluetooth.library.connect.response.BleConnectResponse;
import com.inuker.bluetooth.library.connect.response.BleNotifyResponse;
import com.inuker.bluetooth.library.model.BleGattCharacter;
import com.inuker.bluetooth.library.model.BleGattProfile;
import com.inuker.bluetooth.library.model.BleGattService;
import com.inuker.bluetooth.library.search.SearchRequest;
import com.inuker.bluetooth.library.search.SearchResult;
import com.inuker.bluetooth.library.search.response.SearchResponse;
import com.itsdf07.alog.ALog;
import com.rchat.pocmini.PocApplication;
import com.rchat.pocmini.R;
import com.rchat.pocmini.account.PocAccount;
import com.rchat.pocmini.activity.ble.BlePresenterImpl;
import com.rchat.pocmini.activity.fragment.groups.GroupsPresenterImpl;
import com.rchat.pocmini.activity.listener.MediaListener;
import com.rchat.pocmini.activity.listener.MessageListener;
import com.rchat.pocmini.activity.listener.MessagePttListener;
import com.rchat.pocmini.activity.login.LoginPresenterImpl;
import com.rchat.pocmini.bean2eventbus.BTDeviceBean;
import com.rchat.pocmini.bean2eventbus.BleBean;
import com.rchat.pocmini.bean2eventbus.BluetoothBean;
import com.rchat.pocmini.bean2eventbus.ConnectBleBean;
import com.rchat.pocmini.bean2eventbus.ConnectedBleBean;
import com.rchat.pocmini.bean2eventbus.EventBusLoginBean;
import com.rchat.pocmini.bean2eventbus.MediaListenerBean;
import com.rchat.pocmini.bean2eventbus.MessageListenerBean;
import com.rchat.pocmini.bean2eventbus.MessagePttListenerBean;
import com.rchat.pocmini.bean2eventbus.PowerWakeLockBean;
import com.rchat.pocmini.bean2eventbus.ScanBleBean;
import com.rchat.pocmini.bean2eventbus.ScanBleStateBean;
import com.rchat.pocmini.bean2eventbus.Talk2PttBean;
import com.rchat.pocmini.bean2eventbus.TalkBean;
import com.rchat.pocmini.bean2eventbus.UpdateGroupBean;
import com.rchat.pocmini.bluetooth.BTService;
import com.rchat.pocmini.common.singlepix.ScreenBroadCastListener;
import com.rchat.pocmini.db.MemoryDataStoreModel;
import com.rchat.pocmini.global.AppGlobal;
import com.rchat.pocmini.listener.LocalPhoneStateListener;
import com.rchat.pocmini.message.PocAirtalkeeMessage;
import com.rchat.pocmini.receiver.NetworkReceiver;
import com.rchat.pocmini.util.ListUtil;
import com.rchat.pocmini.util.SPUtil;
import com.rchat.pocmini.util.Sound;
import com.rchat.pocmini.util.SoundPoolUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static android.bluetooth.BluetoothAdapter.STATE_CONNECTED;
import static com.inuker.bluetooth.library.Code.REQUEST_SUCCESS;

/**
 * Created by ljd on 2017/3/15.
 *
 * @Modify sudf 2017.7.24
 * START_STICKY：
 * 如果service进程被kill掉，保留service的状态为开始状态，但不保留递送的intent对象。随后系统会尝试重新创建service，由于服务状态为开始状态，所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service，那么参数Intent将为null。
 * START_NOT_STICKY：
 * “非粘性的”。使用这个返回值时，如果在执行完onStartCommand后，服务被异常kill掉，系统不会自动重启该服务。
 * START_REDELIVER_INTENT：
 * 重传Intent。使用这个返回值时，如果在执行完onStartCommand后，服务被异常kill掉，系统会自动重启该服务，并将Intent的值传入。
 * START_STICKY_COMPATIBILITY：
 * START_STICKY的兼容版本，但不保证服务被kill后一定能重启
 */

public class PocService extends Service implements
        OnAccountListener,//用户登入登出事件
        OnMessageListener,//与用户即时消息相关的接口
        OnMessagePttListener,//本地录制事件
        OnMediaListener //返回与会话中话语权相关的事件
{

    //============= ACCOUNT_RESULT值 ===========
    //正常
    public static final int ACCOUNT_RESULT_OK = AirtalkeeAccount.ACCOUNT_RESULT_OK;
    //用户不正确
    public static final int ACCOUNT_RESULT_ERR_USER_NOTEXIST = AirtalkeeAccount.ACCOUNT_RESULT_ERR_USER_NOTEXIST;
    //密码不正确
    public static final int ACCOUNT_RESULT_ERR_USER_PWD = AirtalkeeAccount.ACCOUNT_RESULT_ERR_USER_PWD;
    //账号已过期
    public static final int ACCOUNT_RESULT_ERR_ACCOUNT_EXPIRE = AirtalkeeAccount.ACCOUNT_RESULT_ERR_ACCOUNT_EXPIRE;
    //账号被管理员禁用或限制
    public static final int ACCOUNT_RESULT_ERR_ACCOUNT_FORBIDDEN = AirtalkeeAccount.ACCOUNT_RESULT_ERR_ACCOUNT_FORBIDDEN;
    //服务器出现异常
    public static final int ACCOUNT_RESULT_ERR_SERVER_UNAVAILABLE = AirtalkeeAccount.ACCOUNT_RESULT_ERR_SERVER_UNAVAILABLE;
    //本地网络访问错误
    public static final int ACCOUNT_RESULT_ERR_NETWORK = AirtalkeeAccount.ACCOUNT_RESULT_ERR_NETWORK;
    //单点登录（有另一个设备用同一个号登录）
    public static final int ACCOUNT_RESULT_ERR_SINGLE = AirtalkeeAccount.ACCOUNT_RESULT_ERR_SINGLE;
    //未授权的终端版本
    public static final int ACCOUNT_RESULT_ERR_LICENSE = AirtalkeeAccount.ACCOUNT_RESULT_ERR_LICENSE;

    public static final String SDK_LOGIN_IPOCID = "IPOCID";
    public static final String SDK_LOGIN_PWD = "PWD";
    public static final String SDK_LOGIN_EXPIREDATE = "EXPIREDATE";

    private static final String TAG = "PocService";
    private static final String TAGACC = TAG + ":OnAccountListener";
    private static final String TAGMSG = TAG + ":OnMessageListener";
    private static final String TAGPTT = TAG + ":OnMessagePttListener";
    private static final String TAGMEDIA = TAG + ":OnMediaListener";

    /**
     * 蓝牙SCO是否已经打开
     * PS:  1、默认是不使用蓝牙设备PTT键的，也就是直接点击手机上App里的PTT键，
     * 所以默认SCO是不用打开的（也可以理解为一直是打开着的），所以初始状态该为true
     * 2、一旦使用蓝牙设备PTT键时，在接收到按下时，需要将该状态改为false,
     * 待收到SCO建立连接并在确保SCO打开了之后，在将该状态改为true
     */
    private boolean isBluetoothScoOn = true;
    /**
     * 是否可以开始讲话
     */
    private boolean isMediaStateTalk = false;

    private final IBinder mBinder = new LocalBinder();
    private List<MessageListener> messageListenerList = new ArrayList<>();
    private List<MessagePttListener> messagePttListenerList = new ArrayList<>();
    private List<MediaListener> mediaListenerList = new ArrayList<>();
    /**
     * 网络状态广播
     */
    private NetworkReceiver mNetworkReceiver;
    private LocalPhoneStateListener mLocalPhoneStateListener;

    public static PocService instance;

    public PocAccount mPocAccount;
//    public static WifiLocKManager mWifiLocKManager;

    PowerManager.WakeLock mWakeLock = null;
    ScreenBroadCastListener mScreenBroadCastListener;

    //-----------------------------------------

    private Boolean isBleClientInit = false;

    private Handler mMainHandler = new Handler(Looper.getMainLooper());

    /**
     * 是否正在通电话
     */
    public static boolean isPhoneCalling = false;

    //ble蓝牙
    private BluetoothClient mClient;
    //绑定的ble蓝牙的mac地址
    private String boundBleMacAddress = "";
    private Map<String, String> mCurrentTalking = new HashMap<>();

    public boolean isPTTPressed() {
        return isPTTPressed;
    }

    public void setPTTPressed(boolean PTTPressed) {
        isPTTPressed = PTTPressed;
    }

    /**
     * 蓝牙设备PTT是否按下
     */
    private boolean isPTTPressed = false;

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    @Override
    public void onCreate() {
        super.onCreate();
        ALog.dTag(TAG, "：...");
        instance = this;
        registerListener();
        registerNetworkReceiver();
        //启动蓝牙服务
        startService(new Intent(this, BTService.class));
        //双APK进程守护服务
        startService(new Intent(this, RchatClientService.class));
        //启动位置定位服务
        startService(new Intent(this, LocationReportService.class));

        mLocalPhoneStateListener = new LocalPhoneStateListener();
        mLocalPhoneStateListener.setListener(this, PhoneStateListener.LISTEN_CALL_STATE);
    }

    //------------------------------------set\get

    public void setBluetoothScoOn(boolean isBluetoothScoOn) {
        this.isBluetoothScoOn = isBluetoothScoOn;
    }

    public boolean isBluetoothScoOn() {
        return isBluetoothScoOn;
    }

    private void setMediaStateTalk(boolean isMediaStateTalk) {
        this.isMediaStateTalk = isMediaStateTalk;
    }

    public boolean isMediaStateTalk() {
        return isMediaStateTalk;
    }

    //------------------------------------

    /**
     * 统一管理注册监听
     */
    private void registerListener() {
        //对讲SDK账号相关监听
        PocAccount.getPocAccountInstance(this).setOnAccountListener(this);
        PocAirtalkeeMessage.getPocAirtalkeeMessageInstance().setOnMessageListener(this);
        PocAirtalkeeMessage.getPocAirtalkeeMessageInstance().setOnMessagePttListener(this);
        //对讲SDK话语权相关监听
        AirtalkeeSessionManager.getInstance().setOnMediaListener(this);

        //第三方EventBus监听
        EventBus.getDefault().register(this);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventBusUpdateMediaListener(MediaListenerBean bean) {
        if (bean == null || !bean.isTarget(this.getClass())) {
            return;
        }
        ALog.dTag("dfsuMessage", "currentEvent = %s,MessageListener = %s", bean.getCurrentEvent(), bean.getListener());
        if (bean.getCurrentEvent() == MediaListenerBean.EVENT_REGISTER_LISTENER) {
            setMediaListener(bean.getListener());
        } else if (bean.getCurrentEvent() == MediaListenerBean.EVENT_UNREGISTER_LISTENER) {
            unregisterMediaListener(bean.getListener());
        }
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventBusUpdateMessageListener(MessageListenerBean bean) {
        if (bean == null || !bean.isTarget(this.getClass())) {
            return;
        }
        ALog.dTag("dfsuMessage", "currentEvent = %s,MessageListener = %s", bean.getCurrentEvent(), bean.getListener());
        if (bean.getCurrentEvent() == MessageListenerBean.EVENT_REGISTER_LISTENER) {
            setMessageListener(bean.getListener());
        } else if (bean.getCurrentEvent() == MessageListenerBean.EVENT_UNREGISTER_LISTENER) {
            unregisterMessageListener(bean.getListener());
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventBusUpdateMessagePttListener(MessagePttListenerBean bean) {
        if (bean == null || !bean.isTarget(this.getClass())) {
            return;
        }
        if (bean.getCurrentEvent() == MessagePttListenerBean.EVENT_REGISTER_LISTENER) {
            setMessagePttListener(bean.getListener());
        } else if (bean.getCurrentEvent() == MessagePttListenerBean.EVENT_UNREGISTER_LISTENER) {
            unregisterMessagePttListener(bean.getListener());
        }
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void scanBle(ScanBleBean b) {
        if (b == null || !b.isTarget(this.getClass())) {
            return;
        }
        if (!isBleClientInit) {
            //启动ble蓝牙服务
            mClient = new BluetoothClient(this);
            isBleClientInit = true;
        }
        // 扫描设备：支持经典蓝牙和BLE设备混合扫描，可自由定制扫描策略如下：
        SearchRequest request = new SearchRequest.Builder()
                .searchBluetoothLeDevice(3000, 3)
                .searchBluetoothLeDevice(2000)
                .build();

        mClient.search(request, new SearchResponse() {
            @Override
            public void onSearchStarted() {
                ScanBleStateBean b = new ScanBleStateBean();
                b.setTarget(this.getClass(), BlePresenterImpl.class, "onEventBusScanStatus");
                b.setCurrentEvent(ScanBleStateBean.SCANNING);
                EventBus.getDefault().post(b);
            }

            @Override
            public void onDeviceFounded(SearchResult device) {
                BleBean b = new BleBean();
                b.setTarget(this.getClass(), BlePresenterImpl.class, "onEventBusBleDataAdd");
                b.setCurrentEvent(BleBean.EVENT_BLE_FIND);
                b.setResult(device);
                if (mClient.getConnectStatus(device.getAddress()) == STATE_CONNECTED) {
                    b.setConnected(true);
                }
                EventBus.getDefault().post(b);
            }

            @Override
            public void onSearchStopped() {
                ScanBleStateBean b = new ScanBleStateBean();
                b.setTarget(this.getClass(), BlePresenterImpl.class, "onEventBusScanStatus");
                b.setCurrentEvent(ScanBleStateBean.STOP_SCAN);
                EventBus.getDefault().post(b);
            }

            @Override
            public void onSearchCanceled() {
                ScanBleStateBean b = new ScanBleStateBean();
                b.setTarget(this.getClass(), BlePresenterImpl.class, "onEventBusScanStatus");
                b.setCurrentEvent(ScanBleStateBean.STOP_SCAN);
                EventBus.getDefault().post(b);
            }
        });
    }

    /**
     * 断开ble蓝牙设备
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onDisConnectBle(final ConnectBleBean bean) {
        if (!bean.isTarget(this.getClass())) {
            return;
        }
        if (bean.getCurrentEvent() != ConnectBleBean.DISCONNECT_BLE) {
            return;
        }
        mClient.disconnect(bean.getDeviceAddress());
    }

    /**
     * 连接ble蓝牙设备
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void connectBle(final ConnectBleBean b) {
        if (!b.isTarget(this.getClass())) {
            return;
        }
        if (b.getCurrentEvent() != ConnectBleBean.CONNECT_BLE) {
            return;
        }
        mClient.connect(b.getDeviceAddress(), new BleConnectResponse() {
            @Override
            public void onResponse(int code, BleGattProfile data) {
                if (code == REQUEST_SUCCESS) {

                    ConnectedBleBean cb = new ConnectedBleBean();
                    cb.setTarget(this.getClass(), BlePresenterImpl.class, "onEventBusBleConnected");
                    cb.setDeviceAddress(b.getDeviceAddress());
                    cb.setCurrentEvent(ConnectedBleBean.CONNECTED_BLE);
                    EventBus.getDefault().post(cb);

                    BluetoothBean bluetoothBean = new BluetoothBean();
                    bluetoothBean.setCurrentEvent(BluetoothBean.EVENT_ENABLE_PTT);
                    bluetoothBean.setTarget(this.getClass(), BTService.class, "onBluetoothEventBus");
                    EventBus.getDefault().post(bluetoothBean);

                    List<BleGattService> serviceList = data.getServices();
                    for (BleGattService service : serviceList) {
                        for (BleGattCharacter characteristic : service.getCharacters()) {
                            // 打开设备通知
                            mClient.notify(b.getDeviceAddress(), service.getUUID(), characteristic.getUuid(), new BleNotifyResponse() {
                                @Override
                                public void onNotify(UUID service, UUID character, byte[] value) {
                                    if (value[0] == 1) {
                                        Talk2PttBean bean = new Talk2PttBean();
                                        bean.setTarget(this.getClass(), BTService.class, "onEventBusTalkStatus");
                                        bean.setCurrentEvent(Talk2PttBean.EVENT_BLE_TALK);
                                        EventBus.getDefault().post(bean);
                                        ALog.e("bleonNotify", value[0] + "");
                                    } else if (value[0] == 0) {
                                        ALog.e("bleonNotify", value[0] + "");
                                        Talk2PttBean bean = new Talk2PttBean();
                                        bean.setTarget(this.getClass(), BTService.class, "onEventBusTalkStatus");
                                        bean.setCurrentEvent(Talk2PttBean.EVENT_BLE_TALK_RELEASE);
                                        EventBus.getDefault().post(bean);
//                                        SoundPoolUtils.getInstance().onPlay(SoundPoolUtils.KEY_SOUND_A2, null);
                                        Sound.playSound(Sound.PLAYER_MEDIA_ME_OFF, PocService.this);
                                    }

                                }

                                @Override
                                public void onResponse(int code) {
                                    if (code == REQUEST_SUCCESS) {
                                        SPHelper.put(SPHelper.SPKeyGlobal.KEY_BLE_MAC, b.getDeviceAddress());
                                    }
                                }
                            });
                        }
                    }
                }
            }
        });
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventPowerWakeLock(PowerWakeLockBean bean) {
        if (bean == null || !bean.isTarget(this.getClass())) {
            return;
        }
        if (PowerWakeLockBean.EVENT_ACQUIRE_POWERWAKELOCK == bean.getCurrentEvent()) {
            acquireWakeLock();
        } else {
            releaseWakeLock();
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Bundle bundle = intent.getExtras();
        if (null != bundle) {
            pocAccountLogin(bundle);
        }
        ALog.d("SDKinterrupt", "onStartCommand flags = %s,startId = %s", flags, startId);
        if ((Boolean) SPUtil.get(this, AppGlobal.KeySP.KEY_SP_ISNOTIFICATION, true)) {
            //通知栏进程保活
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                rchatStartForeground();
            }
        }

        if ((Boolean) SPUtil.get(this, AppGlobal.KeySP.KEY_SP_IS1PIX, true)) {
            //一像素进程保活
            mScreenBroadCastListener = new ScreenBroadCastListener(this);
            mScreenBroadCastListener.registerBroadCast();
        }

//        acquireWakeLock();

        int powerWakeLockStatus = SPHelper.getInteger(SPHelper.SPKeyGlobal.KEY_POWER_WAKELOCK);

        PowerWakeLockBean powerWakeLockBean = new PowerWakeLockBean();
        powerWakeLockBean.setCurrentEvent(powerWakeLockStatus == 1 ?
                PowerWakeLockBean.EVENT_ACQUIRE_POWERWAKELOCK : PowerWakeLockBean.EVENT_RELEASE_POWERWAKELOCK);
        powerWakeLockBean.setTarget(this.getClass(), PocService.class, "onEventPowerWakeLock");
        onEventPowerWakeLock(powerWakeLockBean);

        return START_REDELIVER_INTENT;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        ALog.dTag("ServiceDestory", "onDestroy...");
        EventBus.getDefault().unregister(this);
        PocAccount.getPocAccountInstance(this).setOnAccountListener(null);
        PocAirtalkeeMessage.getPocAirtalkeeMessageInstance().setOnMessageListener(null);
        PocAirtalkeeMessage.getPocAirtalkeeMessageInstance().setOnMessagePttListener(null);
        AirtalkeeSessionManager.getInstance().setOnMediaListener(null);
        unregisterReceiver(mNetworkReceiver);
        if (mLocalPhoneStateListener != null) {
            mLocalPhoneStateListener.setListener(this, PhoneStateListener.LISTEN_NONE);
            mLocalPhoneStateListener = null;
        }

        releaseWakeLock();
//        mWifiLocKManager.releaseWifiLock();
        if ((Boolean) SPUtil.get(this, AppGlobal.KeySP.KEY_SP_IS1PIX, true)) {
            //统一规范，否则外面这个SP的条件是可以不要的
            if (null != mScreenBroadCastListener) {
                mScreenBroadCastListener.unRegisterBroadCast();
            }
        }

        if ((Boolean) SPUtil.get(this, AppGlobal.KeySP.KEY_SP_ISNOTIFICATION, true)) {
            stopForeground(true);//取消最高级进程
        }
        stopService(new Intent(this, BTService.class));
        /**
         * 双APK进程守护服务
         */
        stopService(new Intent(this, RchatClientService.class));
        if (!"".equals(boundBleMacAddress)) {
            mClient.refreshCache(boundBleMacAddress);
            mClient.disconnect(boundBleMacAddress);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    private void rchatStartForeground() {
//        Notification notification = new Notification(R.drawable.icon_my_head, "title",System.currentTimeMillis());
//        PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
//        notification.setLatestEventInfo(this, "Service",  "service is running", pintent);
        Notification notification = new Notification.Builder(this)
                .setContentTitle(String.format(getString(R.string.app_notification_tip), getString(R.string.app_name)))
                .setSmallIcon(R.drawable.icon_my_head)
                .build();
        startForeground(1, notification);//设置最高级进程， id 为 0状态栏的 notification 将不会显示

    }

    //获取电源锁，保持该服务在屏幕熄灭时仍然获取CPU时，保持运行
    private void acquireWakeLock() {
        if (null == mWakeLock) {
            PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, this.getClass().getCanonicalName());
            if (null != mWakeLock) {
                mWakeLock.acquire();
            }
        }
    }

    //释放设备电源锁
    private void releaseWakeLock() {
        if (null != mWakeLock) {
            mWakeLock.release();
            mWakeLock = null;
        }
    }

    /**
     * 登录Airtalkee账号
     */
    private void pocAccountLogin(Bundle bundle) {
        PocAccount.setExpireDate(bundle.getString(SDK_LOGIN_EXPIREDATE));
        mPocAccount = PocAccount.getPocAccountInstance(this);
        mPocAccount.login(bundle.getString(SDK_LOGIN_IPOCID), bundle.getString(SDK_LOGIN_PWD));
        SPUtil.put(this, "ipocId", bundle.getString(SDK_LOGIN_IPOCID));
    }

    //----------------------------------------------------------
    private void registerNetworkReceiver() {
        IntentFilter mFilter = new IntentFilter();
        mNetworkReceiver = new NetworkReceiver();
        mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
//        mFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
//        mFilter.addAction("android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED");
//        mFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(mNetworkReceiver, mFilter);
    }

    public static PocService getInstance() {
        return instance;
    }

    public void setMessageListener(MessageListener listener) {
        ListUtil.add(messageListenerList, listener);
    }

    public void unregisterMessageListener(MessageListener listener) {
        ListUtil.remove(messageListenerList, listener);
    }

    public void setMessagePttListener(MessagePttListener listener) {
        ListUtil.add(messagePttListenerList, listener);
    }

    public void unregisterMessagePttListener(MessagePttListener listener) {
        ListUtil.remove(messagePttListenerList, listener);
    }


    public void setMediaListener(MediaListener listener) {
        ListUtil.add(mediaListenerList, listener);
    }

    public void unregisterMediaListener(MediaListener listener) {
        ListUtil.remove(mediaListenerList, listener);
    }

    public Map<String, String> getCurrentTalking() {
        return mCurrentTalking == null ? new HashMap<String, String>() : mCurrentTalking;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }


    //------------------OnAccountListener start


    /**
     * 账户登录事件回调
     *
     * @param result
     * @see AirtalkeeAccount
     */
    @Override
    public void onLogin(int result) {
        ALog.dTag(TAGACC, "result = %s ", result);
        EventBusLoginBean bean = new EventBusLoginBean();
        bean.setCurrentEvent(result);
        bean.setTarget(this.getClass(), LoginPresenterImpl.class, "onEventBusLoginSDK");
        EventBus.getDefault().post(bean);
        switch (result) {
            case PocService.ACCOUNT_RESULT_OK:
                ToastUtils.showToast(this, getString(R.string.tip_account_result_ok));
                break;
            case PocService.ACCOUNT_RESULT_ERR_USER_NOTEXIST:
                ToastUtils.showToast(this, getString(R.string.tip_account_result_err_user_notexist));
                break;
            case PocService.ACCOUNT_RESULT_ERR_USER_PWD:
                ToastUtils.showToast(this, getString(R.string.tip_account_result_err_user_pwd));
                break;
            case PocService.ACCOUNT_RESULT_ERR_ACCOUNT_EXPIRE:
                ToastUtils.showToast(this, getString(R.string.tip_account_result_err_account_expire));
                break;
            case PocService.ACCOUNT_RESULT_ERR_ACCOUNT_FORBIDDEN:
                ToastUtils.showToast(this, getString(R.string.tip_account_result_err_account_forbidden));
                break;
            case PocService.ACCOUNT_RESULT_ERR_SERVER_UNAVAILABLE:
                ToastUtils.showToast(this, getString(R.string.tip_account_result_err_server_unavailable));
                break;
            case PocService.ACCOUNT_RESULT_ERR_NETWORK:
                ToastUtils.showToast(this, getString(R.string.tip_account_result_err_network));
                break;
            case PocService.ACCOUNT_RESULT_ERR_SINGLE:
                ToastUtils.showToast(this, getString(R.string.tip_account_result_err_single));
                break;
            case PocService.ACCOUNT_RESULT_ERR_LICENSE:
                ToastUtils.showToast(this, getString(R.string.tip_account_result_err_license));
                break;
        }
    }

    /**
     * 账户登出
     */
    @Override
    public void onLogout() {
        ALog.dTag(TAGACC, ": ...");
    }

    /**
     * 账户心跳事件：在运行过程中，网络变化引起的或与服务器实时连接引起的异常变化，会自动产生此事件通知
     *
     * @param beat
     */
    @Override
    public void onHeartbeat(int beat) {
        ALog.dTag(TAGACC, "beat = %s", beat);

        if (beat == AirtalkeeAccount.ACCOUNT_RESULT_ERR_SINGLE) {
            showAnotherLoginDialog();
        }
    }

    @Override
    public void onAccountMatch(int i, String s) {
        ALog.dTag(TAGACC, "i = %s,s = %s", i, s);
    }

    @Override
    public void onServerChanged(String s) {
        ALog.dTag(TAGACC, "s = %s", s);
    }

    //------------------OnAccountListener end

    private void showAnotherLoginDialog() {
        /* @setIcon 设置对话框图标
         * @setTitle 设置对话框标题
         * @setMessage 设置对话框消息提示
         * setXXX方法返回Dialog对象，因此可以链式设置属性
         */
        final AlertDialog.Builder normalDialog = new AlertDialog.Builder(getApplicationContext());

        normalDialog.setMessage("您的账号在另一个地方登陆，你已被迫下线");
        normalDialog.setPositiveButton("确定",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        System.exit(0);
                    }
                });
        normalDialog.setNegativeButton("",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //...To-do
                        System.exit(0);
                    }
                });
        // 显示
        final AlertDialog dialog = normalDialog.create();
        dialog.getWindow().setType((WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
        dialog.setCancelable(false);
        dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                    return true;
                } else {
                    return false; //默认返回 false
                }
            }
        });
        dialog.show();
    }


    //----------OnMessageListener start

    /**
     * 收到其它用户的即时消息
     *
     * @param isCustom   是否为自定义消息
     * @param airMessage 收到的消息对象实例
     */
    @Override
    public void onMessageIncomingRecv(boolean isCustom, AirMessage airMessage) {
        ALog.dTag(TAGMSG, "isCustom = %s,displayName = %s", isCustom, airMessage.getSession().getDisplayName());
        MemoryDataStoreModel.get(this).insertMessage(airMessage);
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageIncomingRecv(isCustom, airMessage);
            }
        }
    }

    /**
     * 当用户登录后，如果有离线消息， SDK 会自动收到离线 消息列表
     *
     * @param list 收到的离线消息列表（一般为多条离线消息）
     */
    @Override
    public void onMessageIncomingRecv(List<AirMessage> list) {
        ALog.dTag(TAGMSG, "list.size = %s", list.size());
        MemoryDataStoreModel.get(this).batchInsertMessage(list);
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageIncomingRecv(list);
            }
        }
    }

    /**
     * 发送的即时消息成功与否的结果
     *
     * @param isCustom   是否为自定义消息
     * @param airMessage 发送的消息对象实例
     *                   此事件在发送结果到来之前可能会被触发多次，每次返回的是发送的中间
     *                   状态，具体状态值，可通过 message.getState()来获得：
     *                   - AirMessage.STATE_NONE = 0，无状态
     *                   - AirMessage.STATE_RES_DOING = 1，正在传输资源数据
     *                   - AirMessage.STATE_RES_FAIL = 2，资源传输失败
     *                   - AirMessage.STATE_SENDING = 3，正在发送消息
     *                   - AirMessage.STATE_RESULT_OK = 4，发送成功
     *                   - AirMessage.STATE_RESULT_FAIL = 5，发送失败
     * @param isSent     是否发送成功
     */
    @Override
    public void onMessageOutgoingSent(boolean isCustom, AirMessage airMessage, boolean isSent) {
        ALog.dTag(TAGMSG, "isCustom = %s,isSent = %s,displayName = %s", isCustom, isSent, airMessage.getSession().getDisplayName());
        if (airMessage.getState() == AirMessage.STATE_RESULT_OK) {
            MemoryDataStoreModel.get(this).insertMessage(airMessage);
        }
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageOutgoingSent(isCustom, airMessage, isSent);
            }
        }
    }

    @Override
    public void onMessageUpdated(AirMessage airMessage) {
        ALog.dTag(TAGMSG, "displayName = %s", airMessage.getSession().getDisplayName());
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageUpdated(airMessage);
            }
        }
    }

    /**
     * 语音消息开始录音的事件
     */
    @Override
    public void onMessageRecordStart() {
        ALog.dTag(TAGMSG, ": ...");
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageRecordStart();
            }
        }
    }

    /**
     * 语音消息停止录音的事件
     *
     * @param seconds 如果录音成功则返回录音的秒数
     *                其它的可能返回值：
     *                -2：未满足最小秒数（1 秒以上）
     *                -3：录音被取消
     * @param msgCode 语音消息的 Code
     */
    @Override
    public void onMessageRecordStop(int seconds, String msgCode) {
        ALog.dTag(TAGMSG, "seconds = %s,msgCode = %s", seconds, msgCode);
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageRecordStop(seconds, msgCode);
            }
        }
    }

    /**
     * 语音消息录音数据传送完成的事件
     *
     * @param msgCode 语音消息的 Code
     * @param resId   语音消息的资源 ID
     */
    @Override
    public void onMessageRecordTransfered(String msgCode, String resId) {
        ALog.dTag(TAGMSG, "msgCode = %s,resId = %s", msgCode, resId);
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageRecordTransfered(msgCode, resId);
            }
        }
    }

    /**
     * 语音消息播放开始加载数据的事件
     *
     * @param msgCode 语音消息的 Code
     * @param resId   语音消息的资源 ID
     */
    @Override
    public void onMessageRecordPlayLoading(String msgCode, String resId) {
        ALog.dTag(TAGMSG, "msgCode = %s,resId = %s", msgCode, resId);
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageRecordPlayLoading(msgCode, resId);
            }
        }
    }

    /**
     * 语音消息播放完成加载数据的事件
     *
     * @param b
     * @param s
     * @param s1
     * @param bytes
     */
    @Override
    public void onMessageRecordPlayLoaded(boolean b, String s, String s1, byte[] bytes) {
        ALog.dTag(TAGMSG, "b = %s,s = %s,s1 = %s", b, s, s1);
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageRecordPlayLoaded(b, s, s1, bytes);
            }
        }
    }

    /**
     * 语音消息开始播放的事件
     *
     * @param msgCode 语音消息的 Code
     * @param resId   语音消息的资源 ID
     */
    @Override
    public void onMessageRecordPlayStart(String msgCode, String resId) {
        ALog.dTag(TAGMSG, "msgCode = %s,resId = %s", msgCode, resId);
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageRecordPlayStart(msgCode, resId);
            }
        }
        EventBus.getDefault().post("");
    }

    /**
     * 语音消息停止播放的事件
     *
     * @param msgCode 语音消息的 Code
     * @param resId   语音消息的资源 ID
     */
    @Override
    public void onMessageRecordPlayStop(String msgCode, String resId) {
        ALog.dTag(TAGMSG, "msgCode = %s,resId = %s", msgCode, resId);
        if (messageListenerList != null && messageListenerList.size() > 0) {
            for (int i = 0; i < messageListenerList.size(); i++) {
                MessageListener listener = messageListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessageRecordPlayStop(msgCode, resId);
            }
        }
    }
    //----------OnMessageListener end

    /**
     * 实时通话的本地录音完成事件
     *
     * @param session 所在会话的实例
     * @param message SDK 自动形成一条消息实例
     * @param msgCode 消息 ID
     * @param resId   录音文件资源 ID，可在 setMediaRealtimeRecordPath 方法设置的 path 目
     *                录下找到以 resID 作为文件名的文件
     */
    @Override
    public void onMessagePttRecord(AirSession session, AirMessage message, String msgCode, String resId) {
        ALog.dTag(TAGPTT, "msgCode = %s,resId = %s,AirSession:displayName = %s,AirMessage:displayName = %s",
                msgCode, resId, session.getDisplayName(), message.getSession().getDisplayName());
        AirContact a = session.getSpeaker();
        message.setInameFrom(a.getDisplayName());
        MemoryDataStoreModel.get(this).insertMessage(message);
        if (messagePttListenerList != null && messagePttListenerList.size() > 0) {
            for (int i = 0; i < messagePttListenerList.size(); i++) {
                MessagePttListener listener = messagePttListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMessagePttRecord(session, message, msgCode, resId);
            }
        }
    }

    //========== OnMediaListener 方法 start ==========//

    /**
     * 本人申请话语权时会第一个回调此事件，可用于 UI 对界面进行状态刷新
     *
     * @param airSession 会话实例
     */
    @Override
    public void onMediaStateTalkPreparing(AirSession airSession) {
        ALog.dTag(TAGMEDIA, "displayName = %s,%s", airSession.getDisplayName(), airSession);
        TalkBean bean = new TalkBean();
        bean.setCurrentEvent(TalkBean.EVENT_TALK_PREPARE);
        bean.setTarget(this.getClass(), PocService.class, "onEventBusTalk");
        bean.setAirSession(airSession);
        onEventBusTalk(bean);
    }

    /**
     * 本人申请到话语权开始讲话的事件
     *
     * @param airSession
     */
    @Override
    public void onMediaStateTalk(AirSession airSession) {
        ALog.dTag(TAGMEDIA, "displayName = %s,%s", airSession.getDisplayName(), airSession);
        setMediaStateTalk(true);
        if (!isPTTPressed) {
            TalkBean bean = new TalkBean();
            bean.setCurrentEvent(TalkBean.EVENT_TALKING);
            bean.setAirSession(airSession);
            bean.setTarget(this.getClass(), PocService.class, "onEventBusTalk");
            onEventBusTalk(bean);
        }

    }

    /**
     * 本人话语权被释放的事件，同时返回话语权被释放的原因
     *
     * @param airSession
     * @param reason     话语权被释放原因的值范围定义在 AirtalkeeSessionManager 中，常量以
     *                   TALK_FINISH_REASON_为前缀，具体为下：
     *                   - TALK_FINISH_REASON_RELEASED(0)：用户主动释放话语权
     *                   - TALK_FINISH_REASON_GRABED(1)：话语权被更高级别的用户抢断而终
     *                   止 -
     *                   TALK_FINISH_REASON_TIMEOUT(2)：申请话语权超时，未申请上话语
     *                   权而结束
     *                   - TALK_FINISH_REASON_TIMEUP(3)：用户发言时长已到，服务器自动终
     *                   止用户的发言
     *                   - TALK_FINISH_REASON_EXCEPTION(4)：由于用户网络原因，连续间隔
     *                   一定时间服务器依然未能收到用户的通话数据包，而产生的异常，从而自
     *                   动收回用户的话语权
     *                   - TALK_FINISH_REASON_LISTEN_ONLY(5)：用户仅有只听权限，不允许
     *                   发言
     *                   - TALK_FINISH_REASON_SPEAKING_FULL(6)：允许讲话人数或排队人数
     *                   已达上限。当频道内不允许排队时，别人在讲话，本人申请话语权会收到
     *                   此事件；当频道内允许排队时，一旦达到排队最大人数再申请话语权，也
     *                   会收到此事件
     */
    @Override
    public void onMediaStateTalkEnd(AirSession airSession, int reason) {
        ALog.dTag(TAGMEDIA, "reason = %s,displayName = %s,%s", reason, airSession.getDisplayName(), airSession);
        setMediaStateTalk(false);
        TalkBean bean = new TalkBean();
        bean.setCurrentEvent(TalkBean.EVENT_TALKED);
        bean.setAirSession(airSession);
        bean.setReason(reason);
        bean.setTarget(this.getClass(), PocService.class, "onEventBusTalk");
        onEventBusTalk(bean);
    }

    /**
     * 别人开始讲话的事件
     *
     * @param airSession
     * @param speaker    讲话人信息
     */
    @Override
    public void onMediaStateListen(AirSession airSession, AirContact speaker) {
        if (mMainHandler != null){
            mMainHandler.removeCallbacksAndMessages(null);
            AudioUtils.getInstance().onRequestAudioFocus();
        }
        String channelId = airSession.getChannel().getId();
        ALog.dTag(TAGMEDIA, "AirSession:displayName = %s,AirContact:displayName = %s,channelId", airSession.getDisplayName(), speaker.getDisplayName(), channelId);
//        if(BTService.getInstance() !=null && BTService.getInstance().isBTConnected){
//            Log.e("PocService", "打开sco");
//            BTService.getInstance().startBluetoothScoOn();
//        }
        mCurrentTalking.put(channelId, channelId);
        PocApplication.getInstance().mAudioManager.setMode(AudioManager.MODE_IN_CALL);
        UpdateGroupBean bean = new UpdateGroupBean();
        bean.setCurrentEvent(UpdateGroupBean.EVENT_GROPUITEM_MEDIASTATELISTEN);
        bean.setTarget(this.getClass(), GroupsPresenterImpl.class, "onEventBusUpdateGroups");
        bean.setAirSession(airSession);
        bean.setAirContact(speaker);
        EventBus.getDefault().post(bean);
        if (mediaListenerList != null && mediaListenerList.size() > 0) {
            for (int i = 0; i < mediaListenerList.size(); i++) {
                MediaListener listener = mediaListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMediaStateListen(airSession, speaker);
            }
        }
    }

    /**
     * 别人结束讲话的事件
     *
     * @param airSession
     */
    @Override
    public void onMediaStateListenEnd(AirSession airSession) {
        String channelId = airSession.getChannel().getId();
        ALog.dTag(TAGMEDIA, "displayName = %s,channelId = %s", airSession.getDisplayName(), channelId);
        if (mMainHandler != null){
            mMainHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    ALog.dTag(TAGMEDIA, "释放了焦点");
                    AudioUtils.getInstance().onAbandonAudioFocus();
                }
            },500);
        }
        mCurrentTalking.remove(channelId);
        UpdateGroupBean groupBean = new UpdateGroupBean();
        groupBean.setCurrentEvent(UpdateGroupBean.EVENT_GROPUITEM_MEDIASTATELISTENEND);
        groupBean.setTarget(this.getClass(), GroupsPresenterImpl.class, "onEventBusUpdateGroups");
        groupBean.setAirSession(airSession);
        EventBus.getDefault().post(groupBean);

//        if(BTService.getInstance() !=null && BTService.getInstance().isBTConnected){
//            Log.e("PocService", "关闭sco");
//            BTService.getInstance().stopBluetoothScoOn();
//        }
        PocApplication.getInstance().mAudioManager.setMode(AudioManager.MODE_NORMAL);
        if (mediaListenerList != null && mediaListenerList.size() > 0) {
            for (int i = 0; i < mediaListenerList.size(); i++) {
                MediaListener listener = mediaListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMediaStateListenEnd(airSession);
            }
        }
    }

    @Override
    public void onMediaStateListenVoice(AirSession airSession) {
        ALog.dTag(TAGMEDIA, "displayName = %s,%s", airSession.getDisplayName(), airSession);
        if (mediaListenerList != null && mediaListenerList.size() > 0) {
            for (int i = 0; i < mediaListenerList.size(); i++) {
                MediaListener listener = mediaListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMediaStateListenVoice(airSession);
            }
        }
    }

    /**
     * 最新排队人列表，排队列表变更时会收到服务器推送过来的此事件
     *
     * @param airSession
     * @param queue      排队人列表
     */
    @Override
    public void onMediaQueue(AirSession airSession, ArrayList<AirContact> queue) {
        ALog.dTag(TAGMEDIA, "displayName = %s, queue = %s", airSession.getDisplayName(), queue.size());
        if (mediaListenerList != null && mediaListenerList.size() > 0) {
            for (int i = 0; i < mediaListenerList.size(); i++) {
                MediaListener listener = mediaListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMediaQueue(airSession, queue);
            }
        }
    }

    /**
     * 当用户在允许排队的频道内申请话语权，同时当前有人正占用话语权时，
     * 服务器允许用户进入排队状态，会返回此事件
     *
     * @param airSession
     */
    @Override
    public void onMediaQueueIn(AirSession airSession) {
        ALog.dTag(TAGMEDIA, "displayName = %s", airSession.getDisplayName());
        if (mediaListenerList != null && mediaListenerList.size() > 0) {
            for (int i = 0; i < mediaListenerList.size(); i++) {
                MediaListener listener = mediaListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMediaQueueIn(airSession);
            }
        }
    }

    /**
     * 当用户已在排队队列中，用户取消话语权后会返回此事件
     *
     * @param airSession
     */
    @Override
    public void onMediaQueueOut(AirSession airSession) {
        ALog.dTag(TAGMEDIA, "displayName = %s", airSession.getDisplayName());
        if (mediaListenerList != null && mediaListenerList.size() > 0) {
            for (int i = 0; i < mediaListenerList.size(); i++) {
                MediaListener listener = mediaListenerList.get(i);
                if (listener == null) {
                    break;
                }
                listener.onMediaQueueOut(airSession);
            }
        }
    }
    //========== OnMediaListener 方法 end ==========//

    public class LocalBinder extends Binder {
        public PocService getService() {
            return PocService.this;
        }
    }

    /**
     * 系统震动
     */
    private void callSystemVibrator() {
        Vibrator vibrator;
        vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
        vibrator.vibrate(new long[]{0, 150}, -1);
    }

    /**
     * 最终对讲状态
     * 1、EVENT_TALK_PREPARE：准备对讲
     * 11、EVENT_TALK_PREPARE_SYNC_SCO_AND_REQUEST：准备开始对讲：SCO建立连接与申请话语权同步进行
     * 12、EVENT_TALK_PREPARE_ASYN_SCO_AFTER_REQUEST：准备开始对讲：SCO建立连接在话语权申请成功之后进行
     * 14、EVENT_TALKING：可以对讲
     * ①有蓝牙设备：申请到话语权-提示音-发起SCO建立-SCO建立成功后震动，失败则结束
     * ②无蓝牙设备：申请到话语权-提示音+震动
     * 2、EVENT_TALKED：对讲结束
     * 3、EVENT_TALK_ERR：对讲异常
     * 31、EVENT_TALK_ERR_HAS：对讲异常 -> 有人正在讲话
     * 32、EVENT_TALK_ERR_FAILED：对讲异常 -> 话语权申请失败
     *
     * @param bean
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventBusTalk(TalkBean bean) {
        if (bean == null || !bean.isTarget(this.getClass())) {
            return;
        }
        ALog.dTag(TAGMEDIA, "getCurrentEvent = %s", bean.getCurrentEvent());
        switch (bean.getCurrentEvent()) {
            case TalkBean.EVENT_TALK_PREPARE:
//                Sound.playSound(Sound.PLAYER_MEDIA_ME_ON, this);
                if (mediaListenerList != null && mediaListenerList.size() > 0) {
                    for (int i = 0; i < mediaListenerList.size(); i++) {
                        MediaListener listener = mediaListenerList.get(i);
                        if (listener == null) {
                            break;
                        }
                        listener.onMediaStateTalkPreparing(bean.getAirSession());
                    }
                }
                break;
            case TalkBean.EVENT_TALKING:
                if (isMediaStateTalk()) {
                    if (isPTTPressed){
                        if (!isBluetoothScoOn()){
                            return;
                        }
                    }else {
                        Sound.playSound(Sound.PLAYER_MEDIA_ME_ON, this);
                    }
                } else {
                    return;
                }
                /**
                 * 连接蓝牙设备发起对讲时，申请到话语权时播报提示音，随后进入SCO建立过程，SCO建立成功后，手机震动
                 */
                callSystemVibrator();

                if (mediaListenerList != null && mediaListenerList.size() > 0) {
                    for (int i = 0; i < mediaListenerList.size(); i++) {
                        MediaListener listener = mediaListenerList.get(i);
                        if (listener == null) {
                            break;
                        }
                        listener.onMediaStateTalk(bean.getAirSession());
                    }
                }
                UpdateGroupBean groupTalkBean = new UpdateGroupBean();
                groupTalkBean.setCurrentEvent(UpdateGroupBean.EVENT_GROPUITEM_MEDIASTATETALK);
                groupTalkBean.setTarget(this.getClass(), GroupsPresenterImpl.class, "onEventBusUpdateGroups");
                groupTalkBean.setAirSession(bean.getAirSession());
                EventBus.getDefault().post(groupTalkBean);
                break;
            case TalkBean.EVENT_TALKED:
                int reason = bean.getReason();
                //如果是有人在对讲时按下对讲回调到该方法的时候，因为没有去开启SCO连接，所以不需要去关闭SCO连接
                if (reason == AirtalkeeSessionManager.TALK_FINISH_REASON_SPEAKING_FULL || reason == AirtalkeeSessionManager.TALK_FINISH_REASON_TIMEOUT) {
                    if (isPTTPressed) {
                        BTDeviceBean talkEndBean = new BTDeviceBean();
                        talkEndBean.setCurrentEvent(BTDeviceBean.EVENT_SCO_CLOSE);
                        bean.setTarget(this.getClass(), BTService.class, "onEventBusBTDevice");
                        EventBus.getDefault().post(talkEndBean);
                    }
                    Sound.playSound(Sound.PLAYER_MEDIA_ERROR, this);
                } else {
                    Sound.playSound(Sound.PLAYER_MEDIA_ME_OFF, this);
                    if (mediaListenerList != null && mediaListenerList.size() > 0) {
                        for (int i = 0; i < mediaListenerList.size(); i++) {
                            MediaListener listener = mediaListenerList.get(i);
                            if (listener == null) {
                                break;
                            }
                            listener.onMediaStateTalkEnd(bean.getAirSession(), reason);
                        }
                    }
                    UpdateGroupBean groupEndBean = new UpdateGroupBean();
                    groupEndBean.setCurrentEvent(UpdateGroupBean.EVENT_GROPUITEM_MEDIASTATETALKEND);
                    groupEndBean.setTarget(this.getClass(), GroupsPresenterImpl.class, "onEventBusUpdateGroups");
                    groupEndBean.setAirSession(bean.getAirSession());
                    groupEndBean.setReason(reason);
                    EventBus.getDefault().post(groupEndBean);
                }
                break;
            case TalkBean.EVENT_TALK_ERR:
                break;
            case TalkBean.EVENT_TALK_ERR_HAS:
                break;
            case TalkBean.EVENT_TALK_ERR_FAILED:
                break;
            default:
                break;
        }
    }

}
